package simulateOS.management.process;

import javafx.collections.ObservableList;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import simulateOS.controller.ProcessPageController;
import simulateOS.entity.*;
import simulateOS.entity.Process;
import simulateOS.management.computerInterface.ProcessInterface;
import simulateOS.management.device.DeviceManager;
import simulateOS.management.memory.MemoryManager;
import simulateOS.utils.RuntimeTimer;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Date: 2022/9/27
 * Time: 15:59
 *
 * @Author SillyBaka
 * Description：
 **/
@Slf4j
@Component
public class ProcessManager implements ProcessInterface {


    @Resource
    private ProcessPageController processPageController;
    @Resource
    private MemoryManager memoryManager;
    @Resource
    private DeviceManager deviceManager;
    @Resource
    private RuntimeTimer runtimeTimer;
    @Resource
    private Blocking_supervisor blocking_supervisor;
    @Resource
    private RR_executor rr_executor;

    private ProcessRunnerFactory processRunnerFactory;


    //todo 待实现
    @Override
    public void createProcess(File file) {
        if(file == null){
            //todo 随机获取一个可执行文件
            file = FAT.getFAT().getARandomExecuteFile();
//            file = (File) FAT.getFAT().getC().getChildren().get(0);
        }
        //todo 创建进程的实际逻辑
//        new ProcessRunner(file);
        if(this.processRunnerFactory == null){
            initProcessRunnerFactory();
        }
        ProcessRunner p =  this.processRunnerFactory.createProcessRunner(file);
    }

    @Override
    public void startToRun() {
        log.info("正在初始化");
//        RR_executor rr_executor =  RR_executor.RRrunner();
//        Blocking_supervisor blocking_supervisor =  Blocking_supervisor.BlockSupervisor();
        Thread RR = new Thread(rr_executor,"rr");
//        Platform.runLater(rr_executor);
        Thread Supervisor = new Thread(blocking_supervisor,"b_s");
//        Platform.runLater(rr_executor);
        RR.start();
        Supervisor.start();
        log.info("运行线程创建成功");
        log.info("监控线程创建成功");
    }

    public void retrieveDevice(ProcessRunner pr) {
        //归还设备，解除阻塞
        Device device = pr.getDevice();
        deviceManager.retrieveDevice(device);
        pr.setDevice(Device.DEFAULT_DEVICE);
    }


    public void refreshBlockingQueueView(Process process,boolean isInsert){
        ObservableList<Process> blockingProcessList = processPageController.getBlockingProcessList();
        if(isInsert){
            blockingProcessList.add(process);
        }else {
            blockingProcessList.remove(process);
        }
    }

    public void destroyProcess(ProcessRunner pr) {
        //终止进程，释放内存
        pr.setStatus(Status.STOP);
        pr.getTimeRunner().destroy();
        processPageController.getReadyProcessList().remove(pr);
        memoryManager.releaseMemory(pr);
        //记录已运行完毕的进程
        processPageController.getEndingProcessList().add(pr);

    }

    public void blockProcesse(Process process) {
        ObservableList<Process> blockingProcessList = processPageController.getBlockingProcessList();

    }






//    /**
//     * 就绪队列中添加或删除进程时 刷新视图
//     * @param process 目标进程
//     * @param isInsert 是否添加
//     */
//    public void refreshReadyQueueView(Process process,boolean isInsert){
//        ObservableList<Process> readyProcessList = processPageController.getReadyProcessList();
//        if(isInsert){
//            readyProcessList.add(process);
//        }else {
//            readyProcessList.remove(process);
//        }
//    }
//    public void refreshBlockingQueueView(){
//        ObservableList<Process> blockingProcessList = processPageController.getBlockingProcessList();
//
//    }

    public void initProcessRunnerFactory(){
        this.processRunnerFactory = new ProcessRunnerFactory();

        this.processRunnerFactory.setProcessManager(this);
        this.processRunnerFactory.setMemoryManager(memoryManager);
        this.processRunnerFactory.setRuntimeTimer(runtimeTimer);
        this.processRunnerFactory.setDeviceManager(deviceManager);

        this.processRunnerFactory.setProcessPageController(processPageController);
        this.processRunnerFactory.setExecutor(processPageController.getPoolExecutor());

    }
}
